var Node = function (val = 0) {
  this.val = val
  this.next = null
}

/**
 * @param {number} k
 */
export var MyCircularQueue = function (k) {
  this.head = null
  this.tail = null
  this.size = 0
  this.capacity = k

  this.fixedHead = null
  this.fixedTail = null
  this.nodeCount = 0
}

/**
 * @param {number} value
 * @return {boolean}
 */
MyCircularQueue.prototype.enQueue = function (value) {
  if (this.isFull()) return false

  let node = null
  if (this.nodeCount < this.capacity) {
    // 未成环
    node = new Node(value)
    this.nodeCount++

    // 第一次 tail = null
    if (this.tail) {
      this.tail.next = node
    }

    // 固定头部节点，只会走一次
    if (!this.fixedHead) {
      this.fixedHead = node
    }

    // node个位满后，变为环形链表
    if (this.nodeCount == this.capacity) {
      node.next = this.fixedHead
    }
  } else {
    // 已成环
    node = this.tail.next
    node.val = value
  }

  this.tail = node
  this.size++

  // head会因为出队，多次变为null
  if (!this.head) {
    this.head = node
  }

  return true
}

/**
 * @return {boolean}
 */
MyCircularQueue.prototype.deQueue = function () {
  if (this.isEmpty()) return false
  // 边界条件，head当前指向最后一个元素，出队后，head = null, tail 指向上次的最后一个元素
  this.head = this.head.next
  this.size--
  return true
}

/**
 * @return {number}
 */
MyCircularQueue.prototype.Front = function () {
  if (this.isEmpty()) return -1
  return this.head.val
}

/**
 * @return {number}
 */
MyCircularQueue.prototype.Rear = function () {
  if (this.isEmpty()) return -1
  return this.tail.val
}

/**
 * @return {boolean}
 */
MyCircularQueue.prototype.isEmpty = function () {
  return this.size == 0
}

/**
 * @return {boolean}
 */
MyCircularQueue.prototype.isFull = function () {
  return this.size == this.capacity
}

/**
 * Your MyCircularQueue object will be instantiated and called as such:
 * var obj = new MyCircularQueue(k)
 * var param_1 = obj.enQueue(value)
 * var param_2 = obj.deQueue()
 * var param_3 = obj.Front()
 * var param_4 = obj.Rear()
 * var param_5 = obj.isEmpty()
 * var param_6 = obj.isFull()
 */
